'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 建筑
 * @author sundbcn@gmail.com (sun debing)
 */

var _ = require('lodash');
var async = require('async');
var moment = require('moment');
var techConf = require('../config/techConf');
var soldierConf = require('../config/soldierConf.js');
var Code = require('../consts/code');
var fightPowerService = require('./fightPowerService.js');
var PlayerManager = require('../libs/playerManager');
var unionGroupModel = require('../models/unionGroupModel.js');
var unionHelpModel = require('../models/unionHelpModel.js');
var unionGroupMgr = require('../mgr/unionGroupMgr.js');
var haveHelpMgr = require('../mgr/haveHelpMgr.js');
var haveHelpModel = require('../models/haveHelpModel.js');

/**
 * 刷新科技队列
 * @param  {[type]} player_manager [description]
 * @return {[type]}                [description]
 */
exports.refreshQue = function (tech_model, update_single, cb) {
    // 判断是否有已到完成升级时间的科技数据没有刷新
    if (!tech_model.up_tech_id) {
        return cb();
    }
    if (moment().unix() >= tech_model.up_tech_end_tm) {
        var tech_id = _upEnd(tech_model, update_single);
        _remove_union_help(tech_model, tech_id, cb);
    } else {
        cb();
    }
};

/**
 * 刷新科技战力
 * @param  {[type]}   tech_model      [description]
 * @return {[type]}             [description]
 */
exports.updateTechPower = function (tech_model, update_single) {
    _updateTechPower(tech_model, update_single);
};

/**
 * 完成升级科技
 * @param  {[type]} player_manager [description]
 * @return {[type]}                [description]
 */
var _upEnd = function (tech_model, update_single) {
    var up_tech_id = tech_model.up_tech_id;
    if (up_tech_id === 0) {
        return;
    }
    if (moment() < tech_model.up_tech_end_tm) {
        return;
    }

    tech_model.addTechLevel(up_tech_id);
    _updateTechPower(tech_model, update_single);
    tech_model.up_tech_id = 0;
    tech_model.up_tech_start_tm = 0;
    tech_model.up_tech_end_tm = 0;
    return up_tech_id;
};

var arr_tech_eff_fld = {
    '13': 'hp', // 弓箭塔:生命值提升X%
    '14': 'min_atk', // 弓箭塔:攻击力提升X%
    '15': 'crit', // 弓箭塔攻击有X%几率暴击
    '16': 'crit_addition', // 弓箭塔:攻击暴击时伤害提升X%
    '17': 'min_atk', // 火炮塔攻击力提升X%
    '18': 'hp', // 火炮塔生命提升X%
    '19': 'knock_down', // 受到火炮塔伤害的敌人有X%几率被击倒
    '20': 'aoe_radius', // 火炮塔炮弹落地后照成伤害范围提升X%
    '21': 'min_atk', // 冰霜塔攻击力提升X%
    '22': 'hp', // 冰霜塔:生命值提升X%
    '23': 'low_move_speed', // 冰霜塔：附加攻击时使得敌人减少 移动 速度X点持续4秒
    '24': 'low_atk_speed', // 冰霜塔：附加攻击时使得敌人减少 攻击 速度X点持续4秒
    '25': 'min_atk', // 闪电塔攻击力提升X%
    '26': 'hp', // 闪电塔生命值提升X%
    '27': 'damage_add_per', // 闪电塔附加攻击时使得敌人受到伤害加深X%持续1.5秒
    '28': 'damage_add_tm', // 闪电塔攻击使得敌人受到伤害加深时间提升至X秒
    '29': 'min_atk', // 投刃塔攻击力提升X%
    '30': 'hp', // 投刃塔:生命值提升X%
    '31': 'prvnt_less_time_atk', // 投刃塔每次弹射伤害抵减降低X%
    '32': 'add_follow_atk_times', // 投刃塔弹射数加X
    '33': 'damage_add', // 龙息塔的伤害提升X%
    '34': 'hp', // 龙息塔生命提升X%
    '35': 'burn_damage_per', // 受到龙息塔攻击的敌人获得燃烧效果。燃烧效果：使得每秒扣除最大生命上限X%伤害持续1.5秒
    '36': 'burn_damage_tm', // 龙息塔燃烧效果时间提升至X秒
    '37': 'min_atk', // 风暴塔的攻击力提升X%
    '38': 'hp', // 风暴塔的生命值提升X%
    '39': 'move_speed', // 风暴塔的攻击时使得敌人移动速度减少X点持续X秒
    '40': 'atk_speed', // 风暴塔的攻击时使得敌人攻击速度减少X点持续X秒
    '41': 'min_atk', // 磁暴塔的攻击力提升X%
    '42': 'hp', // 磁暴塔的生命值提升X%
    '43': 'freeze', // 受到磁暴塔伤害的单位定身X秒
    '44': 'continue_damage', // 磁暴塔炮弹伤害残留X秒每秒造成X点伤害
    '45': 'aoe_radius', // 磁暴塔的炮弹伤害范围提升X%
    '46': 'damage_add', // 地雷伤害提升X%
    '47': 'hp', // 路障生命提升X%
    '48': 'hp', // 兵营生命提升X%
    '54': 'hp', // 城墙的生命值提升X%
    '55': 'hp', // 英雄的生命值提升X%
    '74': 'damage_sub', // 箭塔受到的伤害降低X%
    '75': 'damage_sub', // 火炮塔受到的伤害降低X%
    '76': 'damage_sub', // 冰霜塔受到的伤害降低X%
    '77': 'damage_sub', // 闪电塔受到的伤害降低X%
    '78': 'damage_sub', // 投刃塔受到的伤害降低X%
    '79': 'damage_sub', // 龙息塔受到的伤害降低X%
    '80': 'damage_sub', // 风暴塔受到的伤害降低X%
    '81': 'damage_sub' // 磁暴塔受到的伤害降低X%
};

// '82': 'less_cost', // 箭塔升级时所需资源减少X%
// '83': 'less_cost', // 火炮塔升级时所需资源减少X%
// '84': 'less_cost', // 冰霜塔升级时所需资源减少X%
// '85': 'less_cost', // 闪电塔升级时所需资源减少X%
// '86': 'less_cost', // 投刃塔升级时所需资源减少X%
// '87': 'less_cost', // 龙息塔升级时所需资源减少X%
// '88': 'less_cost', // 风暴塔升级时所需资源减少X%
// '89': 'less_cost'  // 磁暴塔升级时所需资源减少X%

var arr_soldier_tech_eff_fld = {
    '58': 'hp', // 地精士兵的生命值提升X%
    '59': 'min_atk', // 地精士兵的攻击力提升X%
    '60': 'damage_sub', // 地精士兵受到的伤害降低X%
    '61': 'crit', // 地精士兵的暴击提升X%
    '62': 'hp', // 兽人士兵的生命值提升X%
    '63': 'min_atk', // 兽人士兵的攻击力提升X%
    '64': 'damage_sub', // 兽人士兵受到的伤害降低X%
    '65': 'crit', // 兽人士兵的暴击提升X%
    '66': 'hp', // 地狱士兵的生命值提升X%
    '67': 'min_atk', // 地狱士兵的攻击力提升X%
    '68': 'damage_sub', // 地狱士兵受到的伤害降低X%
    '69': 'crit', // 地狱士兵的暴击提升X%
    '70': 'hp', // 天堂士兵的生命值提升X%
    '71': 'min_atk', // 天堂士兵的攻击力提升X%
    '72': 'damage_sub', // 天堂士兵受到的伤害降低X%
    '73': 'crit' // 天堂士兵的暴击提升X%
};

//扩展字段列表
var ex_attr_fld = {
    'knock_down': 1, // 击倒几率
    'low_move_speed': 1, // 减移动加速
    'low_atk_speed': 1, // 减攻击加速
    'prvnt_less_time_atk': 1, // 降低弹射伤害递减X%
    'add_follow_atk_times': 1, // 增加弹射次数
    'burn_damage_per': 1, // 燃烧伤害最大生命上限X%
    'burn_damage_tm': 1, // 燃烧伤害持续时间
    'move_speed': 1, // 风暴塔的攻击时使得敌人移动速度减少X点持续X秒
    'atk_speed': 1, // 风暴塔的攻击时使得敌人攻击速度减少X点持续X秒
    'freeze': 1, // 定身
    'continue_damage': 1, // 伤害残留
    'damage_add_per': 1, // 伤害加深X%(BUFF)
    'damage_add_tm': 1, // 伤害提升时间
    'damage_add': 1, // 伤害提升X%(永久)
    'damage_sub': 1, // 伤害提升X%(永久)
};

// 加成方式: 0按百分比增加/1直接加属性/2直接替换属性值
var arr_eff_type = {
    'crit': 1, // [暴击几率] 增加 xxx
    'crit_addition': 1, // 攻击暴击时伤害提升X%
    'knock_down': 1, // [击倒几率] 增加 XXX
    'prvnt_less_time_atk': 1, // 降低弹射伤害递减X%
    'add_follow_atk_times': 1, // 增加弹射次数
    'damage_add_per': 1, // 伤害加深X%(BUFF)
    'damage_add': 1, // 伤害提升X%(永久)
    'damage_sub': 1, // 受到伤害降低X%(永久)
    'damage_add_tm': 2, // [提升伤害加深] XXX 秒
    'burn_damage_per': 1, // 燃烧伤害最大生命上限X%
    'burn_damage_tm': 2, // 燃烧伤害持续时间
    'move_speed': 1, // 风暴塔的攻击时使得敌人移动速度减少X点持续X秒
    'atk_speed': 1, // 风暴塔的攻击时使得敌人攻击速度减少X点持续X秒
    'freeze': 2, // [定身] XXX 秒
    'low_move_speed': 2, // 移动速度减少X点
    'low_atk_speed': 2, // 攻击速度减少X点
    'continue_damage': 2 // 伤害残留X%
};

/**
 * 建筑附加科技加成
 * @param  {[type]} build_item   [防御建筑]
 * @param  {[type]} tech_type    [科技类型]
 * @param  {[type]} tech_eff_val [效果数值]
 * @return {[type]}              [是否附加成功]
 */
exports.addBuildTechEff = function (build_item, tech_type, tech_eff_val) {
    if (!tech_eff_val) {
        return false;
    }
    build_item.ex_attr = build_item.ex_attr || {};

    var attr = build_item.attr;
    var ex_attr = build_item.ex_attr;

    var tech_eff_fld = arr_tech_eff_fld[tech_type];
    if (!tech_eff_fld) {
        //科技类型无效
        return false;
    }

    var chg_attr = attr;
    if (ex_attr_fld[tech_eff_fld]) {
        chg_attr = ex_attr;
    }

    //取出实际的攻击类型
    if (tech_eff_fld === 'min_atk' && !chg_attr.min_atk) {
        if (!!chg_attr.fire_damage) {
            tech_eff_fld = 'fire_damage';
        } else if (!!chg_attr.ice_damage) {
            tech_eff_fld = 'ice_damage';
        } else if (!!chg_attr.light_damage) {
            tech_eff_fld = 'light_damage';
        } else if (!!chg_attr.city_damage) {
            tech_eff_fld = 'city_damage';
        }
    }
    chg_attr[tech_eff_fld] = chg_attr[tech_eff_fld] || 0;

    var eff_type = arr_eff_type[tech_eff_fld] || 0;

    switch (eff_type) {
    case 0:
        // 按百分比增加
        chg_attr[tech_eff_fld] += chg_attr[tech_eff_fld] * tech_eff_val / 100;
        if (tech_eff_fld === 'min_atk') {
            tech_eff_fld = 'max_atk';
            chg_attr[tech_eff_fld] = chg_attr[tech_eff_fld] || 0;
            chg_attr[tech_eff_fld] += chg_attr[tech_eff_fld] * tech_eff_val / 100;
        }
        break;
    case 1:
        // 直接加属性值
        chg_attr[tech_eff_fld] += tech_eff_val;
        break;
    case 2:
        // 直接替换属性值
        chg_attr[tech_eff_fld] += tech_eff_val;
        break;
    }
    return true;
};

/**
 * 士兵附加科技加成
 * @param  {[type]} soldier_item [士兵]
 * @param  {[type]} tech_type    [科技类型]
 * @param  {[type]} tech_eff_val [效果数值]
 * @return {[type]}              [是否附加成功]
 */
exports.addSoldierTechEff = function (soldier_item, tech_type, tech_eff_val) {
    if (!tech_eff_val) {
        return false;
    }
    soldier_item.ex_attr = soldier_item.ex_attr || {};

    var attr = soldier_item.attr;
    var ex_attr = soldier_item.ex_attr;

    var tech_eff_fld = arr_soldier_tech_eff_fld[tech_type];
    if (!tech_eff_fld) {
        //科技类型无效
        return false;
    }

    var chg_attr = attr;
    if (ex_attr_fld[tech_eff_fld]) {
        chg_attr = ex_attr;
    }

    //取出实际的攻击类型
    if (tech_eff_fld === 'min_atk' && !chg_attr.min_atk) {
        if (!!chg_attr.fire_damage) {
            tech_eff_fld = 'fire_damage';
        } else if (!!chg_attr.ice_damage) {
            tech_eff_fld = 'ice_damage';
        } else if (!!chg_attr.light_damage) {
            tech_eff_fld = 'light_damage';
        } else if (!!chg_attr.city_damage) {
            tech_eff_fld = 'city_damage';
        }
    }
    chg_attr[tech_eff_fld] = chg_attr[tech_eff_fld] || 0;

    var eff_type = arr_eff_type[tech_eff_fld] || 0;

    switch (eff_type) {
    case 0:
        // 按百分比增加
        chg_attr[tech_eff_fld] += chg_attr[tech_eff_fld] * tech_eff_val / 100;
        if (tech_eff_fld === 'min_atk') {
            tech_eff_fld = 'max_atk';
            chg_attr[tech_eff_fld] = chg_attr[tech_eff_fld] || 0;
            chg_attr[tech_eff_fld] += chg_attr[tech_eff_fld] * tech_eff_val / 100;
        }
        break;
    case 1:
        // 直接加属性值
        chg_attr[tech_eff_fld] += tech_eff_val;
        break;
    case 2:
        // 直接替换属性值
        chg_attr[tech_eff_fld] += tech_eff_val;
        break;
    }
    return true;
};

/**
 * 刷新科技战力
 * @param  {[type]}   tech_model      [description]
 * @return {[type]}             [description]
 */
var _updateTechPower = function (tech_model, update_single) {
    var tech_power = 0;
    var tech_type_list = tech_model.tech_list;
    for (var tech_type in tech_type_list) {
        var tech_id_list = tech_type_list[tech_type];
        for (var tech_id in tech_id_list) {
            var tech_lvl = tech_id_list[tech_id];
            var tech_lvl_info = techConf.getTechLvlConf(tech_id, tech_lvl);
            tech_power += tech_lvl_info.fp;
        }
    }
    tech_model.tech_power = tech_power;

    if (!update_single) {
        // 刷新总战力
        var role_id = tech_model.role_id;
        var player_manager = new PlayerManager(role_id);
        fightPowerService.updByIdMainPower(role_id, player_manager, function (err) {
            if (!err) {
                player_manager.save();
            }
        });
    }
};

var _remove_union_help = function (tech_model, tech_id, callback) {
    var player_manager = tech_model.mgr;
    var role_id = player_manager.getRoleId();
    var union_id = 0;
    var union_group_model;
    var only_item = null;
    var have_list_all = [];
    if (!player_manager) {
        player_manager = new PlayerManager(role_id);
        player_manager.tech = tech_model;
    }

    async.waterfall(
        [

            function (cb) {
                player_manager.getModel(
                    ['role', 'bag', 'build', 'task', 'achieve', 'daily_task', 'tech', 'accrued'],
                    cb
                );
            },
            function (cb) {
                var role_model = player_manager.role;
                union_id = role_model.union_id;
                cb();
            },
            function (cb) {
                if (!!union_id) {
                    unionGroupModel.getById(union_id, function (err, union_model) {
                        if (!!err) {
                            console.error('err------------union mgr not ', err);
                        }
                        union_group_model = union_model;
                        cb();
                    });
                } else {
                    cb();
                }
            },
            function (cb) {
                var help_list2 = {
                    union_id: union_id,
                    role_id: role_id,
                    share_id: tech_id,
                    help_type: 2
                };

                unionHelpModel.findUnionHelpItem(help_list2, function (err, item) {
                    only_item = item;
                    cb();
                });
            },
            function (cb) {
                if (!!only_item) {
                    var have_modify_list = [];
                    have_modify_list.push({
                        union_id: union_id,
                        role_id: role_id,
                        require_role_id: only_item.role_id,
                        share_id: tech_id,
                        help_type: 2
                    });

                    // 推送已帮助列表
                    haveHelpMgr.sendHaveHelpChangedMulti(
                        union_id, {
                            have_list: have_modify_list,
                            is_modify: 2
                        },
                        function (err, fails) {
                            if (err) {
                                console.error('send unionGroup message error: %j, fail ids: %j', err, fails);
                                return;
                            }
                        }
                    );
                    haveHelpModel.removeMsg('' + only_item._id, function (err) {
                        cb();
                    });
                } else {
                    cb();
                }
            },
            function (cb) {
                if (!!union_id) {
                    _removeUnionHelp(role_id, union_id, tech_id, cb);
                } else {
                    cb();
                }
            },
            function (cb) {
                haveHelpModel.findUnionHelpList(role_id, function (err, all_have_list) {
                    have_list_all = all_have_list;
                    cb();
                });
            },
            function (cb) {
                if (!!have_list_all) {
                    haveHelpMgr.sendHaveHelpChanged(
                        role_id, {
                            have_list: have_list_all,
                            is_modify: 1
                        },
                        function (err, fails) {
                            if (err) {
                                console.error('send unionGroup message error: %j, fail ids: %j', err, fails);
                                return;
                            }
                            cb();
                        }
                    );
                } else {
                    cb();
                }
            },
            function (cb) {
                if (!!union_group_model) {}
                cb();
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return callback();
            }
            callback();
        }
    );
};

/**
 * 士兵附加科技效果
 * @param  {[type]} player_manager [description]
 * @return {[type]}                [description]
 */
exports.getSoldierAttrWithTechEff = function (soldier_item, tech_model) {
    var self = this;
    var soldier_to_techid = {
        '1': [58, 59, 60, 61],
        '2': [66, 67, 68, 69],
        '3': [62, 63, 64, 65],
        '4': [70, 71, 72, 73]
    };

    var soldier_race = soldierConf.getSoldierTypeConf(soldier_item.soldier_type).race;
    var tech_list = soldier_to_techid[soldier_race] || null;
    if (!tech_list) {
        return;
    }

    _.each(tech_list, function (tech_type) {
        var tech_eff_val = tech_model.getEffByTechType(tech_type);
        self.addSoldierTechEff(soldier_item, tech_type, tech_eff_val);
    });
};

// 移除联盟帮助
var _removeUnionHelp = function (role_id, union_id, tech_id, cb) {
    var help_info = {
        union_id: union_id,
        role_id: role_id,
        share_id: tech_id,
        help_type: 2
    };

    unionHelpModel.removeHelp(help_info, function (err, numberAffected) {
        if (!!err) {
            console.error('err:', err);
            return cb();
        }

        if (numberAffected.n <= 0) {
            // 未申请帮助
            return cb();
        }

        var help_list = {
            is_modify: 2,
            help_list: [help_info]
        };
        unionGroupMgr.sendUnioHelpChangedMulti(
            union_id,
            help_list,
            function (err, fails) {
                if (err) {
                    console.error('send unionGroup message error: %j, fail ids: %j', err, fails);
                    return;
                }
            }
        );

        cb();
    });
};
